package org.firebug.common.tools.ext;

import org.firebug.common.core.dict.Gender;
import org.firebug.common.tools.core.ASCiiTools;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

/**
 * 身份证工具类
 *
 * @Author: 张晓东
 */
public final class IdCardTools {
    private static final int WEIGHTS[] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
    private static final String[] CAPTCHAS = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};
    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");

    public static boolean validate(String idCard) {
        if (idCard == null || idCard.length() != 18) {
            return false;
        }
        String regex = "^[0-9]{17}([0-9]|X)$";
        if (idCard.matches(regex)) {
            return validateDistrict(idCard) && validateBirthdate(idCard) && validateCaptcha(idCard);
        }
        return false;
    }

    private static boolean validateDistrict(String idCard) {
        String district = idCard.substring(0, 6);
        String regex = "^(1[1-5]|2[1-3]|3[1-7]|4[1-6]|5[0-4]|6[1-6])[0-9]{4}$";
        return district.matches(regex);
    }

    private static boolean validateBirthdate(String idCard) {
        String birthdate = idCard.substring(6, 14);
        try {
            return birthdate.equals(LocalDate.parse(birthdate, FORMATTER).format(FORMATTER));
        } catch (RuntimeException e) {
            return false;
        }
    }

    public static LocalDate getBirthdate(String idCard) {
        String birthdate = idCard.substring(6, 14);
        return LocalDate.parse(birthdate, FORMATTER);
    }

    public static Gender getGender(String idCard) {
        String gender = idCard.substring(15, 17);
        return Integer.parseInt(gender) % 2 == 0 ? Gender.F : Gender.M;
    }

    private static boolean validateCaptcha(String idCard) {
        int weight = 0;
        for (int i = 0; i < WEIGHTS.length; i++) {
            weight += ASCiiTools.toDigital(idCard.charAt(i)) * WEIGHTS[i];
        }
        String captcha = idCard.substring(17);
        return captcha.equals(CAPTCHAS[weight % (CAPTCHAS.length)]);
    }

    private IdCardTools() {
    }
}
